// 懒加载管理器
// 实现标签页和编辑器的懒加载机制，优化性能

import { Tab } from '../stores/tabStore';

// 懒加载配置
export interface LazyLoadConfig {
  enabled: boolean;              // 是否启用懒加载
  preloadDistance: number;       // 预加载距离（标签页索引差）
  maxPreloadedTabs: number;      // 最大预加载标签页数量
  unloadDistance: number;        // 卸载距离（标签页索引差）
  contentThreshold: number;      // 内容大小阈值（KB）
  enableVirtualScrolling: boolean; // 是否启用虚拟滚动
  chunkSize: number;             // 内容分块大小（行数）
}

// 默认配置
const DEFAULT_CONFIG: LazyLoadConfig = {
  enabled: true,
  preloadDistance: 2,
  maxPreloadedTabs: 5,
  unloadDistance: 5,
  contentThreshold: 100, // 100KB
  enableVirtualScrolling: true,
  chunkSize: 1000, // 1000行
};

// 标签页加载状态
export enum LoadState {
  Unloaded = 'unloaded',     // 未加载
  Loading = 'loading',       // 加载中
  Loaded = 'loaded',         // 已加载
  Preloaded = 'preloaded',   // 预加载
  Unloading = 'unloading',   // 卸载中
}

// 懒加载项
export interface LazyLoadItem {
  tabId: string;
  state: LoadState;
  priority: number;          // 加载优先级
  lastAccessed: number;      // 最后访问时间
  contentSize: number;       // 内容大小（字节）
  isVisible: boolean;        // 是否可见
  loadPromise?: Promise<void>; // 加载Promise
}

// 懒加载管理器
export class LazyLoadManager {
  private config: LazyLoadConfig;
  private items = new Map<string, LazyLoadItem>();
  private loadQueue: string[] = [];
  private unloadQueue: string[] = [];
  private isProcessing = false;
  private activeTabId: string | null = null;
  private tabOrder: string[] = [];

  constructor(config: Partial<LazyLoadConfig> = {}) {
    this.config = { ...DEFAULT_CONFIG, ...config };
  }

  // 注册标签页
  registerTab(tab: Tab, index: number): void {
    const contentSize = new Blob([tab.content]).size;
    
    const item: LazyLoadItem = {
      tabId: tab.id,
      state: LoadState.Unloaded,
      priority: this.calculatePriority(index),
      lastAccessed: Date.now(),
      contentSize,
      isVisible: false,
    };

    this.items.set(tab.id, item);
    this.scheduleProcessing();
  }

  // 注销标签页
  unregisterTab(tabId: string): void {
    this.items.delete(tabId);
    this.removeFromQueues(tabId);
  }

  // 更新标签页顺序
  updateTabOrder(newOrder: string[], activeTabId: string | null): void {
    this.tabOrder = newOrder;
    this.activeTabId = activeTabId;

    // 重新计算优先级
    newOrder.forEach((tabId, index) => {
      const item = this.items.get(tabId);
      if (item) {
        item.priority = this.calculatePriority(index);
      }
    });

    this.scheduleProcessing();
  }

  // 标记标签页为可见
  setTabVisible(tabId: string, visible: boolean): void {
    const item = this.items.get(tabId);
    if (item) {
      item.isVisible = visible;
      item.lastAccessed = Date.now();
      
      if (visible) {
        this.prioritizeLoad(tabId);
      }
    }
  }

  // 获取标签页加载状态
  getLoadState(tabId: string): LoadState {
    const item = this.items.get(tabId);
    return item?.state || LoadState.Unloaded;
  }

  // 是否应该懒加载
  shouldLazyLoad(tab: Tab): boolean {
    if (!this.config.enabled) return false;
    
    const contentSize = new Blob([tab.content]).size / 1024; // KB
    return contentSize > this.config.contentThreshold;
  }

  // 计算优先级
  private calculatePriority(index: number): number {
    const activeIndex = this.activeTabId ? this.tabOrder.indexOf(this.activeTabId) : -1;
    
    if (activeIndex === -1) return 100 - index;
    
    const distance = Math.abs(index - activeIndex);
    return Math.max(0, 100 - distance * 10);
  }

  // 优先加载指定标签页
  private prioritizeLoad(tabId: string): void {
    // 从队列中移除
    this.removeFromQueues(tabId);
    
    // 添加到队列前端
    this.loadQueue.unshift(tabId);
    
    this.scheduleProcessing();
  }

  // 从队列中移除
  private removeFromQueues(tabId: string): void {
    this.loadQueue = this.loadQueue.filter(id => id !== tabId);
    this.unloadQueue = this.unloadQueue.filter(id => id !== tabId);
  }

  // 调度处理
  private scheduleProcessing(): void {
    if (this.isProcessing) return;
    
    // 使用 requestIdleCallback 在空闲时处理
    if ('requestIdleCallback' in window) {
      (window as any).requestIdleCallback(() => this.processQueues());
    } else {
      setTimeout(() => this.processQueues(), 0);
    }
  }

  // 处理队列
  private async processQueues(): Promise<void> {
    if (this.isProcessing) return;
    
    this.isProcessing = true;
    
    try {
      // 更新队列
      this.updateQueues();
      
      // 处理加载队列
      await this.processLoadQueue();
      
      // 处理卸载队列
      await this.processUnloadQueue();
    } finally {
      this.isProcessing = false;
    }
  }

  // 更新队列
  private updateQueues(): void {
    const activeIndex = this.activeTabId ? this.tabOrder.indexOf(this.activeTabId) : -1;
    
    this.tabOrder.forEach((tabId, index) => {
      const item = this.items.get(tabId);
      if (!item) return;
      
      const distance = activeIndex >= 0 ? Math.abs(index - activeIndex) : index;
      
      // 决定是否应该加载
      const shouldLoad = item.isVisible || 
                        distance <= this.config.preloadDistance ||
                        item.state === LoadState.Loading;
      
      // 决定是否应该卸载
      const shouldUnload = !item.isVisible && 
                          distance > this.config.unloadDistance &&
                          item.state === LoadState.Loaded;
      
      if (shouldLoad && item.state === LoadState.Unloaded) {
        if (!this.loadQueue.includes(tabId)) {
          this.loadQueue.push(tabId);
        }
      }
      
      if (shouldUnload) {
        if (!this.unloadQueue.includes(tabId)) {
          this.unloadQueue.push(tabId);
        }
      }
    });
    
    // 按优先级排序加载队列
    this.loadQueue.sort((a, b) => {
      const itemA = this.items.get(a);
      const itemB = this.items.get(b);
      return (itemB?.priority || 0) - (itemA?.priority || 0);
    });
    
    // 限制预加载数量
    const loadedCount = Array.from(this.items.values())
      .filter(item => item.state === LoadState.Loaded || item.state === LoadState.Preloaded)
      .length;
    
    if (loadedCount >= this.config.maxPreloadedTabs) {
      // 只保留高优先级的加载请求
      this.loadQueue = this.loadQueue.slice(0, Math.max(0, this.config.maxPreloadedTabs - loadedCount));
    }
  }

  // 处理加载队列
  private async processLoadQueue(): Promise<void> {
    const batchSize = 2; // 每次处理2个
    const batch = this.loadQueue.splice(0, batchSize);
    
    const loadPromises = batch.map(tabId => this.loadTab(tabId));
    await Promise.all(loadPromises);
  }

  // 处理卸载队列
  private async processUnloadQueue(): Promise<void> {
    const batchSize = 3; // 每次卸载3个
    const batch = this.unloadQueue.splice(0, batchSize);
    
    const unloadPromises = batch.map(tabId => this.unloadTab(tabId));
    await Promise.all(unloadPromises);
  }

  // 加载标签页
  private async loadTab(tabId: string): Promise<void> {
    const item = this.items.get(tabId);
    if (!item || item.state !== LoadState.Unloaded) return;
    
    item.state = LoadState.Loading;
    
    try {
      // 模拟异步加载过程
      await new Promise(resolve => setTimeout(resolve, 100));
      
      item.state = item.isVisible ? LoadState.Loaded : LoadState.Preloaded;
      item.lastAccessed = Date.now();
      
      console.log(`Lazy loaded tab: ${tabId}`);
    } catch (error) {
      console.error(`Failed to load tab ${tabId}:`, error);
      item.state = LoadState.Unloaded;
    }
  }

  // 卸载标签页
  private async unloadTab(tabId: string): Promise<void> {
    const item = this.items.get(tabId);
    if (!item || item.state === LoadState.Unloaded) return;
    
    item.state = LoadState.Unloading;
    
    try {
      // 模拟异步卸载过程
      await new Promise(resolve => setTimeout(resolve, 50));
      
      item.state = LoadState.Unloaded;
      
      console.log(`Unloaded tab: ${tabId}`);
    } catch (error) {
      console.error(`Failed to unload tab ${tabId}:`, error);
    }
  }

  // 获取统计信息
  getStats() {
    const states = Array.from(this.items.values()).reduce((acc, item) => {
      acc[item.state] = (acc[item.state] || 0) + 1;
      return acc;
    }, {} as Record<LoadState, number>);
    
    const totalMemory = Array.from(this.items.values())
      .filter(item => item.state === LoadState.Loaded || item.state === LoadState.Preloaded)
      .reduce((total, item) => total + item.contentSize, 0);
    
    return {
      states,
      totalMemory: totalMemory / (1024 * 1024), // MB
      queueSizes: {
        load: this.loadQueue.length,
        unload: this.unloadQueue.length,
      },
    };
  }

  // 更新配置
  updateConfig(newConfig: Partial<LazyLoadConfig>): void {
    this.config = { ...this.config, ...newConfig };
    this.scheduleProcessing();
  }

  // 获取配置
  getConfig(): LazyLoadConfig {
    return { ...this.config };
  }

  // 清理资源
  destroy(): void {
    this.items.clear();
    this.loadQueue = [];
    this.unloadQueue = [];
    this.isProcessing = false;
  }
}

// 单例实例
let lazyLoadManager: LazyLoadManager | null = null;

// 获取懒加载管理器
export const getLazyLoadManager = (config?: Partial<LazyLoadConfig>): LazyLoadManager => {
  if (!lazyLoadManager) {
    lazyLoadManager = new LazyLoadManager(config);
  }
  return lazyLoadManager;
};

// 重置懒加载管理器
export const resetLazyLoadManager = (): void => {
  if (lazyLoadManager) {
    lazyLoadManager.destroy();
    lazyLoadManager = null;
  }
};
